package com.itlong.cloud.operate.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.operate.OperateUserManagePageDTO;
import com.itlong.cloud.POJO.PO.DeviceBusinessChangeLogPO;
import com.itlong.cloud.POJO.PO.DeviceBusinessElevatorChangeLogPO;
import com.itlong.cloud.POJO.PO.DeviceBusinessEntranceChangeLogPO;
import com.itlong.cloud.POJO.VO.app.AppUserCacheVO;
import com.itlong.cloud.POJO.VO.operate.OperateActiveUserVO;
import com.itlong.cloud.POJO.VO.operate.OperateUserManageVO;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.CloudElevatorChangeBusinessEnum;
import com.itlong.cloud.enumerate.CloudEntranceChangeBusinessEnum;
import com.itlong.cloud.enumerate.OperateUserActiveQueryTypeEnum;
import com.itlong.cloud.enumerate.SmartCommunityEnum;
import com.itlong.cloud.operate.dao.IOperateUserManageDao;
import com.itlong.cloud.operate.service.IOperateUserManageService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 *      运营—APP用户-用户管理服务接口实现类。
 * <desc/>
 *
 * @createDate 2017/9/21.
 */
@Service
public class OperateUserManageServiceImpl implements IOperateUserManageService {

    private static final Logger LOG = LoggerFactory.getLogger(OperateUserManageServiceImpl.class);

    @Autowired
    IOperateUserManageDao iOperateUserManageDao;

    @Autowired
    private RedisService<AppUserCacheVO> redisService;

    @Autowired
    private MessageSender messageSender;

     /**
      * <desc>
      *      根据用户ID获取用户信息。
      * <desc/>
      *
      * @param  userId
      * @return   返回用户详细信息
      * @author shengen.T
      * @createDate 2017/9/21
      */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public OperateUserManageVO getUserInfo(String userId) {

        return  iOperateUserManageDao.getUserInfo(userId);
    }

   /**
    * <desc>
    *      获取用户分页信息。
    * <desc/>
    *
    * @param  pageDTO 请求参数对象
    * @return  用户列表信息
    * @author shengen.T
    * @createDate 2017/9/22
    */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<OperateUserManageVO> getPage(OperateUserManagePageDTO pageDTO) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(pageDTO);
        //分页类默认pageSize为20
        Page<OperateUserManageVO> page = new Page<>();
        page.getPage().setPageSize(pageDTO.getPageSize());
        page.getPage().setCurrentPage(pageDTO.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        //填充返回数据集
        List<OperateUserManageVO> pageData = iOperateUserManageDao.getUserInfoList(params);
        //处理用户管理的项目
        if((pageData!=null)&&(pageData.size()>0)){
            pageData.forEach(userInfo->{
                if(StringUtils.isNotBlank(userInfo.getProjectName())){
                    String[] roomNumArr = StringHandlerUtil.splitString(userInfo.getRoomNum());
                    String[] projectNameArr = StringHandlerUtil.splitString(userInfo.getProjectName());
                    StringBuilder sb = new StringBuilder("");
                    for(int i=0;i<roomNumArr.length;i++){
                        //删除房间为0的判断,为了展示一卡通项目
//                        if("0".equals(roomNumArr[i])){
//                            projectNameArr[i]="";
//                            continue;
//                        }
                    }
                    for(int y=0;y<projectNameArr.length;y++){
                        sb.append(projectNameArr[y]).append(",");
                    }
                    if(projectNameArr.length>0){
                        String tmp = sb.toString();
                        tmp = StringUtils.isBlank(tmp)?tmp:tmp.substring(0,tmp.length()-1);
                        userInfo.setProjectName(tmp);
                    }

                }
            });
        }
        //填充返回数据集
        page.setRows(pageData,iOperateUserManageDao.getPageCount(params));
        return page;
    }

     /**
      * <desc>
      *      设置用户使用状态—启用/禁用。
      * <desc/>
      *
      * @param  userId 用户ID
      * @param  status 1正常 2禁用
      * @return
      * @author shengen.T
      * @createDate 2017/9/22
      */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public  boolean setUserStatus(String userId,Integer status) throws Exception  {
        boolean flag=false;
        Integer res = iOperateUserManageDao.setUserStatus(userId,status);
       if(res>0&&2==status){
           AppUserCacheVO appUserCacheVO = redisService.getObject(RedisConstant.APP_LOGIN+userId,AppUserCacheVO.class);
           if (appUserCacheVO != null) {
               appUserCacheVO.setStatus(status);
               flag = redisService.set(RedisConstant.APP_LOGIN + userId, RedisConstant.LOGIN_OUT_APP_USER_TOKEN_TIME, appUserCacheVO);
           }else {
               flag=true;
           }
       }else if(res>0&&1==status){
           flag=true;
       }
       //重新发送2号指令
        List<String> projectIds = iOperateUserManageDao.getUserPorject(userId);
       for (String projectId : projectIds) {
           List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
           JSONObject json = new JSONObject();
           json.put("userId", userId);
           json.put("projectId", projectId);
           DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                   new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT, json,projectId);
           changeLogPOS.add(deviceBusinessChangeLogPO);
           JSONObject dataJs = new JSONObject();
           dataJs.put("data",changeLogPOS);
           messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                   JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                   RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

           //云电梯
           DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                   = new DeviceBusinessElevatorChangeLogPO(projectId,
                   CloudElevatorChangeBusinessEnum.PUSH_USER_PROJECT,json.toJSONString());
           List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
           deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
           dataJs.put("data",deviceElevatorChangeLogPOS);
           messageSender.send(
                   RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                   JsonUtil.toJSON(dataJs),
                   RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                   RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);

           // 云门禁
           List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
           changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, json, projectId));
           dataJs.put("data", changeEntranceLogPOS);
           //发送云门禁指令
           messageSender.send(
                   RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                   JSON.toJSONString(dataJs),
                   RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                   RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
           );

           //发送临时权限数据
           List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
           List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
           List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
           Map<String,Object> auth = new HashMap<>();
           auth.put("userId",userId);
           auth.put("projectId",projectId);
           auth.put("type",1);
           DeviceBusinessChangeLogPO po=new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth),projectId);
           changes.add(po);
           DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth));
           elevatorChanges.add(elevatorPo);
           DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
           entranceChanges.add(entrancePO);
           JSONObject pushJs = new JSONObject();
           pushJs.put("data",changes);
           //发送云对讲业务指令
           messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
           pushJs.put("data",elevatorChanges);
           //推送云电梯业务指令
           messageSender.send(
                   RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                   JsonUtil.toJSON(pushJs),
                   RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                   RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
           //发送云门禁业务指令
           pushJs.put("data",entranceChanges);
           messageSender.send(
                   RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                   JSON.toJSONString(pushJs),
                   RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                   RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
           );
       }
       return flag;
    }

    /**
     * <desc>
     *      根据查询条件查询今日/本周/本月的用户活跃度
     * </desc>
     *
     * @param timeFlag
     * @return
     * @Author Zhu.yj
     * @createDate  2019/10/31
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public OperateActiveUserVO getActiveUser(String timeFlag, String searchTime,String userId) throws Exception {
        OperateActiveUserVO operateActiveUserVO=new OperateActiveUserVO();
        List<Map<String,Object>> activeUserList=iOperateUserManageDao.getActiveUser(timeFlag,searchTime);
        List<Map<String,Object>> activeUserListAll=new ArrayList<>();
        switch (timeFlag){
            case "1":
                activeUserListAll=this.getActiveListAll(activeUserList, OperateUserActiveQueryTypeEnum.DAY.getUnitTimeQuantity(),OperateUserActiveQueryTypeEnum.DAY.getTimeUnit());
                break;
            case "2":
                activeUserListAll=this.getActiveListAll(activeUserList,OperateUserActiveQueryTypeEnum.WEEK.getUnitTimeQuantity(),OperateUserActiveQueryTypeEnum.WEEK.getTimeUnit());
                break;
            case "3":
                SimpleDateFormat dateFormat=new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1);
                activeUserListAll=this.getActiveListAll(activeUserList, DateUtil.getDaysOfMonth(dateFormat.parse(searchTime)),OperateUserActiveQueryTypeEnum.MONTH.getTimeUnit());
                break;
            case "4":
                activeUserListAll=this.getActiveListAll(activeUserList,OperateUserActiveQueryTypeEnum.YEAR.getUnitTimeQuantity(),OperateUserActiveQueryTypeEnum.YEAR.getTimeUnit());
                break;
        }
        operateActiveUserVO.setActiveUserList(activeUserListAll);
        operateActiveUserVO.setTime(searchTime);
        return operateActiveUserVO;
    }

    /**
     * <desc>
     *      查询注册用户量
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate  2019/11/1
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public String getPageCount() throws Exception {
        Integer registerUserCount=iOperateUserManageDao.getPageCount(null);
        return registerUserCount.toString();
    }
    /**
     * <desc>
     *      将返回的用户活跃度为空的时/周/天/月的数据补0
     * </desc>
     *
     * @param activeUserList 读取的用户活跃度
     * @param unitTimeQuantity 单位时间数量
     * @param timeUnits 时间单位
     * @return
     * @Author Zhu.yj
     * @createDate  2019/11/4
     */
    private List<Map<String,Object>> getActiveListAll(List<Map<String,Object>> activeUserList,Integer unitTimeQuantity,String timeUnits){
        List<Map<String,Object>> activeUserListAll=new ArrayList<>();
        //如果返回的数据条数与查询条件的数量匹配，则直接返回
        if(activeUserList.size()==unitTimeQuantity){
            activeUserListAll=activeUserList;
            return activeUserListAll;
        }
        int j=1;
        for(int i=0;i<activeUserList.size();i++,j++){
            int unit=Integer.parseInt(activeUserList.get(i).get(timeUnits).toString());
            //若某天/周/月无数据，则将该天数据活跃度设置为0
            while(unit!=j){
                Map<String, Object> hoursMap=new HashMap<>();
                hoursMap.put(timeUnits,j);
                hoursMap.put("ipCount",0);
                activeUserListAll.add(hoursMap);
                j++;
            }
            activeUserListAll.add(activeUserList.get(i));
        }
        while (activeUserListAll.size()<unitTimeQuantity){
            Map<String, Object> hoursMap=new HashMap<>();
            hoursMap.put(timeUnits,j++);
            hoursMap.put("ipCount",0);
            activeUserListAll.add(hoursMap);
        }
        return activeUserListAll;
    }
}
